<!DOCTYPE html>


<html lang="zh-CN">
  

    <head>
      <meta charset="utf-8" />
       
      <meta name="keywords" content="webshan.king" />
       
      <meta
        name="viewport"
        content="width=device-width, initial-scale=1, maximum-scale=1"
      />
      <title>webpack |  单铁虎的博客</title>
  <meta name="generator" content="hexo-theme-ayer">
      
      <link rel="shortcut icon" href="/images/科比.png" />
       
<link rel="stylesheet" href="/dist/main.css">

      
<link rel="stylesheet" href="/css/fonts/remixicon.css">

      
<link rel="stylesheet" href="/css/custom.css">
 
      <script src="https://cdn.staticfile.org/pace/1.2.4/pace.min.js"></script>
       
 

      <link
        rel="stylesheet"
        href="https://cdn.jsdelivr.net/npm/@sweetalert2/theme-bulma@5.0.1/bulma.min.css"
      />
      <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11.0.19/dist/sweetalert2.min.js"></script>

      <!-- mermaid -->
      
      <style>
        .swal2-styled.swal2-confirm {
          font-size: 1.6rem;
        }
      </style>
    </head>
  </html>
</html>


<body>
  <div id="app">
    
      
    <main class="content on">
      <section class="outer">
  <article
  id="pots-webpack"
  class="article article-type-pots"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h1 class="article-title sea-center" style="border-left:0" itemprop="name">
  webpack
</h1>
 

      
    </header>
     
    <div class="article-meta">
      <a href="/2022/05/23/webpack/" class="article-date">
  <time datetime="2022-05-23T03:16:06.000Z" itemprop="datePublished">2022-05-23</time>
</a>   
<div class="word_count">
    <span class="post-time">
        <span class="post-meta-item-icon">
            <i class="ri-quill-pen-line"></i>
            <span class="post-meta-item-text"> 字数统计:</span>
            <span class="post-count">1.8k</span>
        </span>
    </span>

    <span class="post-time">
        &nbsp; | &nbsp;
        <span class="post-meta-item-icon">
            <i class="ri-book-open-line"></i>
            <span class="post-meta-item-text"> 阅读时长≈</span>
            <span class="post-count">6 分钟</span>
        </span>
    </span>
</div>
 
    </div>
      
    <div class="tocbot"></div>




  
    <div class="article-entry" itemprop="articleBody">
       
  <h2 id="对-webpack-理解？解决了什么问题？"><a href="#对-webpack-理解？解决了什么问题？" class="headerlink" title="对 webpack 理解？解决了什么问题？"></a>对 webpack 理解？解决了什么问题？</h2><p>webpack 是一个用现代 JavaScript 行用程序的静态模块打包工具<br>静态模块：在开发阶段，可以被 webpack 直接引用的资源。</p>
<p>wepack 的能力：<br>1.【编译代码能力】，提高了效率，解决浏览器兼容问题；<br>2.【模块整合能力】，提高性能，可维护性，解决浏览器频繁请求文件的问题；<br>3.【万物皆可模块能力】，项目维护性增强，支持不同种类的前端模块类型，统一的模块化方案，所有资源文件的加载都有可以通过代码控制。</p>
<h2 id="2-webpack-构建流程？"><a href="#2-webpack-构建流程？" class="headerlink" title="2. webpack 构建流程？"></a>2. webpack 构建流程？</h2><ol>
<li>初始化流程： 从配置文件 和 Shell 语句中读取与合并参数，并初始化需要使用的插件和配置插件等执行环境所需要的参数</li>
</ol>
<p>2.编译构建流程：从 Entry 发出，针对每个 Module 串行调用对应的 Loader 去翻译文件内容，再找到该 Module，递归的进行编译处理</p>
<p>3.输出流程： 对边以后的 Module 组合成 Chunk ( 代码块 )，把 Chunk 转换成文件，输出到文件系统</p>
<p>初始化 option ，开始编译 ，从 entry 开始递归的分析依赖，对每个依赖模块进行 build，对模块位置进行解析，开始构建某个模块，将 loader 加载完成的 module 进行编译，生成 AST ( 抽象语法树 )，遍历 AST ，当遇到 requir 等调用表达式是，收集依赖，所有的依赖 build 完成，开始优化，输出到 dist 目录</p>
<h2 id="3-Webpack-中常见的-Loader-？解决了什么问题？"><a href="#3-Webpack-中常见的-Loader-？解决了什么问题？" class="headerlink" title="3. Webpack 中常见的 Loader ？解决了什么问题？"></a>3. Webpack 中常见的 Loader ？解决了什么问题？</h2><p>loader 用于对模块的 “源代码” 进行转换，在 import 或  “加载时” 预处理文件</p>
<h2 id="4-Webpack-中常见的-Plugin-解决了什么问题？"><a href="#4-Webpack-中常见的-Plugin-解决了什么问题？" class="headerlink" title="4. Webpack 中常见的 Plugin ? 解决了什么问题？"></a>4. Webpack 中常见的 Plugin ? 解决了什么问题？</h2><p>Plugin 赋予 Webpack 各种灵活的功能，例如打包优化、资源管理、环境变量注入等，他们会运行在 Webpack 的不同阶段（钩子&#x2F; 生命周期），贯穿了 webpack 整个编译周期，目的在于解决 loader 无法实现的其他事</p>
<h2 id="5-Webpack-说说-Loader-和-Plugin-的区别？-编写-Loader-、Plugin-思路？"><a href="#5-Webpack-说说-Loader-和-Plugin-的区别？-编写-Loader-、Plugin-思路？" class="headerlink" title="5.  Webpack  说说 Loader 和 Plugin 的区别？ 编写 Loader 、Plugin 思路？"></a>5.  Webpack  说说 Loader 和 Plugin 的区别？ 编写 Loader 、Plugin 思路？</h2><p>区别：</p>
<p>loader 运行在打包文件之前：实质是一个转换器，将 A 文件变成形成 B 文件，单纯的文件格式转换；<br>plugin 在整个编译周期都起作用，在 Webpack 运行的生命周期中广播出许多事件， plugin 可以监听这些事件，在合适的时机通过 Webpack 提供的 API 改变输出的结果<br>编写 loader 需要遵循单一原则，每个 loader 只做一种“转义”工作。每个 loader 拿到的都是源文件内容（source），可以通过返回值的方式将处理后的内容输出，也可以调用 this.callback() 方法，将内容返回给 Webpack。还可以通过 this.async() 生成一个 callback 函数，再用这个 callback 将处理后的内容输出出去。也可以通过开发 loader 的工具函数集 —- loader-utils</p>
<p>编写 plugin ：通过监听特定事件</p>
<h2 id="6-Webpack-的热更新是如何做到的？-原理是什么？"><a href="#6-Webpack-的热更新是如何做到的？-原理是什么？" class="headerlink" title="6.  Webpack 的热更新是如何做到的？ 原理是什么？"></a>6.  Webpack 的热更新是如何做到的？ 原理是什么？</h2><p>HMR （ Hot Module Replacement ）</p>
<p>原理： </p>
<p> 通过 webpack-dev-server 创建两个服务器: 提供静态资源的服务（ Express ）和 Socket 服务<br> Express server 负责直接提供静态资源的服务 ( 打包后资源直接被浏览器请求和解析）<br> Socket server 是一个 websocket 的长连接，双方可以互相通信<br> 当 socket server监听到对应的模块发生变化时，会生成两个文件 .json ( manifest 文件 ) 和 .js （ unpdate chunk ）<br> 通过长连接，socket server 可以直接将这两个文件主动发送给客户端 （ 浏览器）<br> 浏览器拿到两个新的文件后，通过 HMR runtime 机制，加载这两个文件，并且针对修改的模块进行更新 </p>
<h2 id="7-Webpack-proxy-工作原理？-为什么能跨域？"><a href="#7-Webpack-proxy-工作原理？-为什么能跨域？" class="headerlink" title="7. Webpack proxy 工作原理？ 为什么能跨域？"></a>7. Webpack proxy 工作原理？ 为什么能跨域？</h2><p>proxy 工作原理： 实质利用 http-proxy-middleware 这个 http 代理中间件，实现请求转发给其他服务器</p>
<p>跨域：（ 服务器和服务器之间请求数据并不会存在跨域行为，跨域行为是浏览器安全策略限制 ）</p>
<p>在开发阶段， webpack-dev-server 会启动一个本地开发服务器，所以我们的应用在开发阶段是独立运行在 localhost 的一个端口上,而后端服务器有事运行在另外一个地址上。所以在开发阶段中，由于浏览器同源策略的原因，当本地访问后端就会出现跨域请求。</p>
<p>解决跨域： 当本地发送请求的时候，代理服务器响应该请求，并将请求转发到目标服务器上，目标服务器响应数据后再将数据返回给代理服务器，最终再由代理服务器将数据响应给本地。</p>
<h2 id="8-如何借助-Webpack-来优化前端性能"><a href="#8-如何借助-Webpack-来优化前端性能" class="headerlink" title="8. 如何借助 Webpack 来优化前端性能"></a>8. 如何借助 Webpack 来优化前端性能</h2><p>可以通过文件体积大小入手，其次还可通过分包的形式、减少http请求次数等方式，实现对前端性能的优化 </p>
<p> JS、CSS、Html 代码 压缩</p>
<p> 文件大小 压缩</p>
<p> 图片 压缩</p>
<p> Tree Shaking ( 消除死代码 )</p>
<p> 代码分离</p>
<p> 内联 chunk</p>
<h2 id="9-如何提高-Webpack-的构建速度？"><a href="#9-如何提高-Webpack-的构建速度？" class="headerlink" title="9.如何提高 Webpack 的构建速度？"></a>9.如何提高 Webpack 的构建速度？</h2><p>主要可以从优化搜索时间、缩小文件搜索范围、减少不必要的编译等方面入手</p>
<p>优化 loader 配置 （ 通过配置 include、exclude、test属性来匹配文 ）<br>合理使用 resolve.extensions<br>优化 resolve.modules （ 第三方模块的绝对路径，以减少寻找 ）<br>优化 resolve.alias （ alias给一些常用的路径起一个别名,例如：@）<br>使用 DLLPlugin 插件<br>使用 cache-loader<br>terser 启动多线程<br>合理使用 sourceMap</p>
<h2 id="10-与-Webpack-类似的工具还有哪些"><a href="#10-与-Webpack-类似的工具还有哪些" class="headerlink" title="10. 与 Webpack 类似的工具还有哪些"></a>10. 与 Webpack 类似的工具还有哪些</h2><p>Rollup  (  Vue、React 和 Three.js )<br>Parcel （  零配置、傻瓜式 ）<br>Snowpack ( 闪电般快速，较为复杂、Webpack 和 Parcel 的替代方案)<br>Webpack 的优势：</p>
<p>智能解析： 对 CommonJS、AMD、ES6 的语法做了兼容<br>万物模块： 对 js、css、图片等资源文件都支持打包<br>开箱即用： 集成 HRM、Tree-Shaking 等功能<br>代码分割： 可以将代码切割成不同的 chunk，实现按需加载，降低了初始化时间<br>插件系统： 具有强大的 Plugin 接口，具有更好的灵活性和扩展性<br>易于调试：支持 ScoureUrls 和 ScoureMap<br>快速运行： Webpack 使用异步 IO 并具有多级缓存，这使得 Webpack 很快且在增量编译上更加快<br>生态环境好：社区更丰富，出现问题更容易解决</p>
<h2 id="11-webpack-常用字段"><a href="#11-webpack-常用字段" class="headerlink" title="11. webpack 常用字段"></a>11. webpack 常用字段</h2><p>main：定义了 npm 包的入口文件<br>mudule: 定义了 npm 包的 ESM 规范的入口文件<br>browser: 定义了 npm 包在 browser 环境下的入口文件</p>
<h2 id="Webpack-常用插件"><a href="#Webpack-常用插件" class="headerlink" title="Webpack 常用插件"></a>Webpack 常用插件</h2><ol>
<li>webpack、webpack-cli 、webpack-dev-server</li>
<li>html-webpack-plugin （ 打包 html 文件 ）</li>
<li>clean-webpack-plugin （ 打包前删除输出目录 ）</li>
<li>webpack-merge ( 合并 webpack 配置)</li>
<li>optimize-css-assets-webpack-plugin ( css 压缩 )</li>
<li>style-loader ( 将 css 插入到 html )</li>
<li>postcss-loader ( 处理 css 的兼容性 ) 和 autoprefixer 一起用</li>
<li>file-loader ( 处理图片文件 )</li>
<li>url-loader ( 将图片转换成 base64 格式 )</li>
<li>mini-css-extract-plugin ( 将 css 单独打包成一个文件 )</li>
<li>terser-webpack-plugin ( 压缩 JS 代码 )</li>
<li>@babel&#x2F;perset-env ( 处理 js 的浏览器兼容问题 )</li>
</ol>
 
      <!-- reward -->
      
      <div id="reword-out">
        <div id="reward-btn">
          打赏
        </div>
      </div>
      
    </div>
    

    <!-- copyright -->
    
    <div class="declare">
      <ul class="post-copyright">
        <li>
          <i class="ri-copyright-line"></i>
          <strong>版权声明： </strong>
          
          本博客所有文章除特别声明外，著作权归作者所有。转载请注明出处！
          
        </li>
      </ul>
    </div>
    
    <footer class="article-footer">
       
<div class="share-btn">
      <span class="share-sns share-outer">
        <i class="ri-share-forward-line"></i>
        分享
      </span>
      <div class="share-wrap">
        <i class="arrow"></i>
        <div class="share-icons">
          
          <a class="weibo share-sns" href="javascript:;" data-type="weibo">
            <i class="ri-weibo-fill"></i>
          </a>
          <a class="weixin share-sns wxFab" href="javascript:;" data-type="weixin">
            <i class="ri-wechat-fill"></i>
          </a>
          <a class="qq share-sns" href="javascript:;" data-type="qq">
            <i class="ri-qq-fill"></i>
          </a>
          <a class="douban share-sns" href="javascript:;" data-type="douban">
            <i class="ri-douban-line"></i>
          </a>
          <!-- <a class="qzone share-sns" href="javascript:;" data-type="qzone">
            <i class="icon icon-qzone"></i>
          </a> -->
          
          <a class="facebook share-sns" href="javascript:;" data-type="facebook">
            <i class="ri-facebook-circle-fill"></i>
          </a>
          <a class="twitter share-sns" href="javascript:;" data-type="twitter">
            <i class="ri-twitter-fill"></i>
          </a>
          <a class="google share-sns" href="javascript:;" data-type="google">
            <i class="ri-google-fill"></i>
          </a>
        </div>
      </div>
</div>

<div class="wx-share-modal">
    <a class="modal-close" href="javascript:;"><i class="ri-close-circle-line"></i></a>
    <p>扫一扫，分享到微信</p>
    <div class="wx-qrcode">
      <img src="//api.qrserver.com/v1/create-qr-code/?size=150x150&data=http://example.com/2022/05/23/webpack/" alt="微信分享二维码">
    </div>
</div>

<div id="share-mask"></div>  
    </footer>
  </div>

   
  <nav class="article-nav">
    
      <a href="/2022/05/24/vue%E7%9A%84%E6%A0%B8%E5%BF%83/" class="article-nav-link">
        <strong class="article-nav-caption">上一篇</strong>
        <div class="article-nav-title">
          
            veu的核心是什么
          
        </div>
      </a>
    
    
  </nav>

   
 
   
    
    <script src="https://cdn.staticfile.org/twikoo/1.4.18/twikoo.all.min.js"></script>
    <div id="twikoo" class="twikoo"></div>
    <script>
        twikoo.init({
            envId: ""
        })
    </script>
 
</article>

</section>
      <footer class="footer">
  <div class="outer">
    <ul>
      <li>
        Copyrights &copy;
        2015-2022
        <i class="ri-heart-fill heart_icon"></i> 单铁虎
      </li>
    </ul>
    <ul>
      <li>
        
      </li>
    </ul>
    <ul>
      <li>
        
        
        <span>
  <span><i class="ri-user-3-fill"></i>访问人数:<span id="busuanzi_value_site_uv"></span></span>
  <span class="division">|</span>
  <span><i class="ri-eye-fill"></i>浏览次数:<span id="busuanzi_value_page_pv"></span></span>
</span>
        
      </li>
    </ul>
    <ul>
      
    </ul>
    <ul>
      
    </ul>
    <ul>
      <li>
        <!-- cnzz统计 -->
        
        <script type="text/javascript" src='https://s9.cnzz.com/z_stat.php?id=1278069914&amp;web_id=1278069914'></script>
        
      </li>
    </ul>
  </div>
</footer>    
    </main>
    <div class="float_btns">
      <div class="totop" id="totop">
  <i class="ri-arrow-up-line"></i>
</div>

<div class="todark" id="todark">
  <i class="ri-moon-line"></i>
</div>

    </div>
    <aside class="sidebar on">
      <button class="navbar-toggle"></button>
<nav class="navbar">
  
  <div class="logo">
    <a href="/"><img src="/images/科比.jpg.jpg" alt="单铁虎的博客"></a>
  </div>
  
  <ul class="nav nav-main">
    
    <li class="nav-item">
      <a class="nav-item-link" href="/">主页</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/archives">归档</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/categories">分类</a>
    </li>
    
  </ul>
</nav>
<nav class="navbar navbar-bottom">
  <ul class="nav">
    <li class="nav-item">
      
      <a class="nav-item-link nav-item-search"  title="搜索">
        <i class="ri-search-line"></i>
      </a>
      
      
      <a class="nav-item-link" target="_blank" href="/atom.xml" title="RSS Feed">
        <i class="ri-rss-line"></i>
      </a>
      
    </li>
  </ul>
</nav>
<div class="search-form-wrap">
  <div class="local-search local-search-plugin">
  <input type="search" id="local-search-input" class="local-search-input" placeholder="Search...">
  <div id="local-search-result" class="local-search-result"></div>
</div>
</div>
    </aside>
    <div id="mask"></div>

<!-- #reward -->
<div id="reward">
  <span class="close"><i class="ri-close-line"></i></span>
  <p class="reward-p"><i class="ri-cup-line"></i>请我喝杯咖啡吧~</p>
  <div class="reward-box">
    
    
    <div class="reward-item">
      <img class="reward-img" src="/images/%E6%89%93%E8%B5%8F.jpg">
      <span class="reward-type">微信</span>
    </div>
    
  </div>
</div>
    
<script src="/js/jquery-3.6.0.min.js"></script>
 
<script src="/js/lazyload.min.js"></script>

<!-- Tocbot -->
 
<script src="/js/tocbot.min.js"></script>

<script>
  tocbot.init({
    tocSelector: ".tocbot",
    contentSelector: ".article-entry",
    headingSelector: "h1, h2, h3, h4, h5, h6",
    hasInnerContainers: true,
    scrollSmooth: true,
    scrollContainer: "main",
    positionFixedSelector: ".tocbot",
    positionFixedClass: "is-position-fixed",
    fixedSidebarOffset: "auto",
  });
</script>

<script src="https://cdn.staticfile.org/jquery-modal/0.9.2/jquery.modal.min.js"></script>
<link
  rel="stylesheet"
  href="https://cdn.staticfile.org/jquery-modal/0.9.2/jquery.modal.min.css"
/>
<script src="https://cdn.staticfile.org/justifiedGallery/3.8.1/js/jquery.justifiedGallery.min.js"></script>

<script src="/dist/main.js"></script>

<!-- ImageViewer -->
 <!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

    <!-- Background of PhotoSwipe. 
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>

    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">

        <!-- Container that holds slides. 
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>

        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">

            <div class="pswp__top-bar">

                <!--  Controls are self-explanatory. Order can be changed. -->

                <div class="pswp__counter"></div>

                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

                <button class="pswp__button pswp__button--share" style="display:none" title="Share"></button>

                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                        <div class="pswp__preloader__cut">
                            <div class="pswp__preloader__donut"></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div>
            </div>

            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>

            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>

            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>

        </div>

    </div>

</div>

<link rel="stylesheet" href="https://cdn.staticfile.org/photoswipe/4.1.3/photoswipe.min.css">
<link rel="stylesheet" href="https://cdn.staticfile.org/photoswipe/4.1.3/default-skin/default-skin.min.css">
<script src="https://cdn.staticfile.org/photoswipe/4.1.3/photoswipe.min.js"></script>
<script src="https://cdn.staticfile.org/photoswipe/4.1.3/photoswipe-ui-default.min.js"></script>

<script>
    function viewer_init() {
        let pswpElement = document.querySelectorAll('.pswp')[0];
        let $imgArr = document.querySelectorAll(('.article-entry img:not(.reward-img)'))

        $imgArr.forEach(($em, i) => {
            $em.onclick = () => {
                // slider展开状态
                // todo: 这样不好，后面改成状态
                if (document.querySelector('.left-col.show')) return
                let items = []
                $imgArr.forEach(($em2, i2) => {
                    let img = $em2.getAttribute('data-idx', i2)
                    let src = $em2.getAttribute('data-target') || $em2.getAttribute('src')
                    let title = $em2.getAttribute('alt')
                    // 获得原图尺寸
                    const image = new Image()
                    image.src = src
                    items.push({
                        src: src,
                        w: image.width || $em2.width,
                        h: image.height || $em2.height,
                        title: title
                    })
                })
                var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, {
                    index: parseInt(i)
                });
                gallery.init()
            }
        })
    }
    viewer_init()
</script> 
<!-- MathJax -->

<!-- Katex -->

<!-- busuanzi  -->
 
<script src="/js/busuanzi-2.3.pure.min.js"></script>
 
<!-- ClickLove -->

<!-- ClickBoom1 -->

<!-- ClickBoom2 -->

<!-- CodeCopy -->

<!-- CanvasBackground -->
 
<script src="/js/dz.js"></script>
 
<script>
  if (window.mermaid) {
    mermaid.initialize({ theme: "forest" });
  }
</script>


    
    

  </div>
</body>

</html>